package com.hbfec.fileserver.controller;

import com.hbfec.fileserver.constant.CacheKeys;
import com.hbfec.fileserver.constant.ErrorCode;
import com.hbfec.fileserver.constant.FileStatus;
import com.hbfec.fileserver.constant.Tag;
import com.hbfec.fileserver.json.Response;
import com.hbfec.fileserver.service.CacheService;
import com.hbfec.fileserver.service.DbService;
import com.hbfec.fileserver.service.FastDFSService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * 文件删除Controller
 */
@RestController
public class DeleteController {
    private static final Logger LOGGER = LoggerFactory.getLogger(DeleteController.class);

    @Value("${fileserver.exist.valid-freq}")
    private Long validFreq;
    @Value("${fileserver.exist.valid-count-limit}")
    private Integer validCountLimit;

    @Autowired
    private DbService dbService;
    @Autowired
    private CacheService cacheService;
    @Autowired
    private FastDFSService fastDFSService;

    /**
     * 文件删除
     * 当调用FastDFS删除文件失败，直接忽略；
     * 因为数据库里已将该文件标记为已删除，定时任务会结合（status!=FileStatus.UPLOADED and 超过过期时间）删除这些文件
     *
     * @param uuid     文件的唯一标识
     * @param request  request
     * @param response response
     * @return 结果
     */
    @RequestMapping(value = "/file/{uuid}", method = RequestMethod.DELETE)
    public Response delete(@PathVariable(value = "uuid", required = true) String uuid,
                           HttpServletRequest request, HttpServletResponse response) {
        // 验证文件信息是否还在缓存中，没有入库
        try {
            boolean exist = cacheService.exists(
                    String.format("%s%s_%s", CacheKeys.FILE_STATUS, uuid, FileStatus.UPLOADED),
                    validCountLimit, validFreq);
            if (exist) {
                return new Response(Tag.FAILURE, ErrorCode.TIME_OUT, "服务忙，请稍后重试", null);
            }
        } catch (Exception cacheEx) {
            return new Response(Tag.FAILURE, ErrorCode.UNKNOWN_ERROR, "验证缓存中是否存在文件信息时出现异常", null);
        }
        // 根据uuid获取文件详情
        Map<String, Object> fileDetail = null;
        try {
            fileDetail = dbService.queryFileWithUuidAndStatus(uuid, FileStatus.UPLOADED);
        } catch (EmptyResultDataAccessException emptyResultEX) {
            return new Response(Tag.FAILURE, ErrorCode.SPECIFIED_OBJECT_CANNOT_BE_FOUND, "文件不存在，删除失败", null);
        } catch (Exception dbEX) {
            return new Response(Tag.FAILURE, ErrorCode.DATABASE_ERROR, "数据库中查询文件发生异常", null);
        }
        // 将文件删除信息插入入库缓存
        try {
            if (!cacheService.lpush(
                    String.format("%s%s_%s", CacheKeys.FILE_STATUS, uuid, FileStatus.DELETED),
                    "", CacheKeys.FILE_QUEUE,
                    String.format("%s | %s | %s | %s | %s | %s | %s", uuid, fileDetail.get("url"),
                            fileDetail.get("name"), fileDetail.get("size"), fileDetail.get("createdate"),
                            fileDetail.get("expire"), FileStatus.DELETED))) {
                throw new Exception("文件删除信息插入入库缓存失败");
            }
        } catch (Exception cacheEx) {
            return new Response(Tag.FAILURE, ErrorCode.UNKNOWN_ERROR, "文件删除信息插入入库缓存失败", null);
        }
        // 解析url
        String[] urlParts = ((String) fileDetail.get("url")).split("/", 3);
        // 调用FastDFS删除文件，删除失败直接忽略
        fastDFSService.deleteFile(urlParts[1], urlParts[2]);
        return new Response(Tag.SUCCESS, ErrorCode.SUCCESS, "成功", null);
    }
}
